home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / decprom / fsIndex.c < prev    next >
C/C++ Source or Header  |  1990-02-16  |  6KB  |  243 lines

  1. /* 
  2.  * fsIndex.c --
  3.  *
  4.  *    Routines to allow moving through a files block pointers.
  5.  *
  6.  * Copyright 1986 Regents of the University of California
  7.  * All rights reserved.
  8.  */
  9.  
  10. #ifdef notdef
  11. static char rcsid[] = "$Header: /sprite/src/boot/decprom/RCS/fsIndex.c,v 1.1 90/02/16 16:14:13 shirriff Exp $ SPRITE (Berkeley)";
  12. #endif not lint
  13.  
  14. #include "sprite.h"
  15. #include "fsBoot.h"
  16. #include "kernel/byte.h"
  17.  
  18. char    firstBlockBuffer[FS_BLOCK_SIZE];
  19. char    secondBlockBuffer[FS_BLOCK_SIZE];
  20.  
  21.  
  22. /*
  23.  *----------------------------------------------------------------------
  24.  *
  25.  * MakePtrAccessible --
  26.  *
  27.  *    Make the block pointer in the file descriptor accessible.  This
  28.  *    may entail reading in indirect blocks and locking them down in the
  29.  *    cache.
  30.  *
  31.  * Results:
  32.  *    None.
  33.  *
  34.  * Side effects:
  35.  *    Indirect blocks are locked down in the cache.
  36.  *
  37.  *----------------------------------------------------------------------
  38.  */
  39.  
  40. static ReturnStatus
  41. MakePtrAccessible(handlePtr, indexInfoPtr, descPtr)
  42.     register    Fsio_FileIOHandle     *handlePtr;
  43.     register    BlockIndexInfo      *indexInfoPtr;
  44.     register    Fsdm_FileDescriptor *descPtr;
  45. {
  46.     register     int          *blockAddrPtr;
  47.  
  48.     /* 
  49.      * Read in the first block.
  50.      */
  51.  
  52.     if (indexInfoPtr->firstBlockNil) {
  53.     FsDeviceBlockIO(FS_READ, &fsDevice,
  54.               descPtr->indirect[indexInfoPtr->indexType],
  55.               FS_FRAGMENTS_PER_BLOCK, firstBlockBuffer);
  56.     }
  57.  
  58.     blockAddrPtr = 
  59.     (int *) (firstBlockBuffer + sizeof(int) * indexInfoPtr->firstIndex);
  60.  
  61.     if (indexInfoPtr->indexType == FS_INDIRECT) {
  62.     indexInfoPtr->blockAddrPtr = blockAddrPtr;
  63.     return(SUCCESS);
  64.     }
  65.  
  66.     /* 
  67.      * Get the second level block.
  68.      */
  69.  
  70.     FsDeviceBlockIO(FS_READ, &fsDevice, *blockAddrPtr,
  71.                FS_FRAGMENTS_PER_BLOCK, secondBlockBuffer);
  72.     indexInfoPtr->blockAddrPtr = 
  73.     (int *) (secondBlockBuffer + sizeof(int) * indexInfoPtr->secondIndex);
  74.  
  75.     return(SUCCESS);
  76. }
  77.  
  78.  
  79. /*
  80.  *----------------------------------------------------------------------
  81.  *
  82.  * FsGetFirstIndex --
  83.  *
  84.  *    Initialize the index structure.  This will set up the index info
  85.  *    structure so that it contains a pointer to the desired block pointer.
  86.  *
  87.  * Results:
  88.  *    A status indicating whether there was sufficient space to allocate
  89.  *    indirect blocks.
  90.  *
  91.  * Side effects:
  92.  *    The index structure is initialized.
  93.  *
  94.  *----------------------------------------------------------------------
  95.  */
  96.  
  97. ReturnStatus
  98. FsGetFirstIndex(handlePtr, blockNum, indexInfoPtr)
  99.     register Fsio_FileIOHandle        *handlePtr;    /* Handle for file that are 
  100.                           indexing. */
  101.     register int        blockNum;      /* Where to start indexing. */
  102.     register BlockIndexInfo *indexInfoPtr; /* Index structure to initialize.*/
  103. {
  104.     register Fsdm_FileDescriptor *descPtr;
  105.     register int          indirectBlock;
  106.  
  107.     descPtr = handlePtr->descPtr;
  108.     indexInfoPtr->firstBlockNil = TRUE;
  109.     indexInfoPtr->blockNum = blockNum;
  110.  
  111.     if (blockNum < FSDM_NUM_DIRECT_BLOCKS) {
  112.     /*
  113.      * This is a direct block.
  114.      */
  115.     indexInfoPtr->indexType = FS_DIRECT;
  116.     indexInfoPtr->blockAddrPtr = &descPtr->direct[blockNum];
  117.     return(SUCCESS);
  118.     }
  119.  
  120.     /*
  121.      * Is an indirect block.
  122.      */
  123.  
  124.     blockNum -= FSDM_NUM_DIRECT_BLOCKS;
  125.     indirectBlock = blockNum / FSDM_INDICES_PER_BLOCK;
  126.     if (indirectBlock == 0) {
  127.     /*
  128.      * This is a singly indirect block.
  129.      */
  130.     indexInfoPtr->indexType = FS_INDIRECT;
  131.     indexInfoPtr->firstIndex = blockNum;
  132.     } else {
  133.     /*
  134.      * This a doubly indirect block.
  135.      */
  136.     indexInfoPtr->indexType = FS_DBL_INDIRECT;
  137.     indexInfoPtr->firstIndex = indirectBlock - 1;
  138.     indexInfoPtr->secondIndex = blockNum -
  139.                     indirectBlock * FSDM_INDICES_PER_BLOCK;
  140.     }
  141.  
  142.     /*
  143.      * Finish off by making the block pointer accessible.  This may include
  144.      * reading indirect blocks into the cache.
  145.      */
  146.  
  147.     return(MakePtrAccessible(handlePtr, indexInfoPtr, descPtr));
  148. }
  149.  
  150.  
  151. /*
  152.  *----------------------------------------------------------------------
  153.  *
  154.  * FsGetNextIndex --
  155.  *
  156.  *    Put the correct pointers in the index structure to access the
  157.  *    block after the current block.
  158.  *
  159.  * Results:
  160.  *    A status indicating whether there was sufficient space to allocate
  161.  *    indirect blocks if they were needed.
  162.  *
  163.  * Side effects:
  164.  *    The allocation structure is modified.
  165.  *
  166.  *----------------------------------------------------------------------
  167.  */
  168.  
  169. ReturnStatus
  170. FsGetNextIndex(handlePtr, indexInfoPtr)
  171.     register Fsio_FileIOHandle       *handlePtr;    /* Handle for file that is being
  172.                           indexed. */
  173.     register BlockIndexInfo *indexInfoPtr; /* Index structure to set up. */
  174. {
  175.     register Boolean          accessible = FALSE;
  176.     register Fsdm_FileDescriptor *descPtr;
  177.  
  178.     descPtr = handlePtr->descPtr;
  179.     indexInfoPtr->blockNum++;
  180.  
  181.     /*
  182.      * Determine whether we are now in direct, indirect or doubly indirect
  183.      * blocks.
  184.      */
  185.  
  186.     switch (indexInfoPtr->indexType) {
  187.     case FS_DIRECT:
  188.         if (indexInfoPtr->blockNum < FSDM_NUM_DIRECT_BLOCKS) {
  189.         /*
  190.          * Still in the direct blocks.
  191.          */
  192.         indexInfoPtr->blockAddrPtr++;
  193.         accessible = TRUE;
  194.         } else {
  195.         /*
  196.          * Moved into indirect blocks.
  197.          */
  198.         indexInfoPtr->indexType = FS_INDIRECT;
  199.         indexInfoPtr->firstIndex = 0;
  200.         }
  201.         break;
  202.     case FS_INDIRECT:
  203.         if (indexInfoPtr->blockNum < 
  204.             FSDM_NUM_DIRECT_BLOCKS + FSDM_INDICES_PER_BLOCK) {
  205.         /*
  206.          * Still in singly indirect blocks.
  207.          */
  208.         indexInfoPtr->blockAddrPtr++;
  209.         accessible = TRUE;
  210.         break;
  211.        } else {
  212.         /*
  213.          * Moved into doubly indirect blocks.
  214.          */
  215.         indexInfoPtr->firstIndex = 0;
  216.         indexInfoPtr->secondIndex = 0;
  217.         indexInfoPtr->indexType = FS_DBL_INDIRECT;
  218.         indexInfoPtr->firstBlockNil = TRUE;
  219.         }
  220.         break;
  221.     case FS_DBL_INDIRECT:
  222.         indexInfoPtr->secondIndex++;
  223.         if (indexInfoPtr->secondIndex == FSDM_INDICES_PER_BLOCK) {
  224.         indexInfoPtr->firstIndex++;
  225.         indexInfoPtr->secondIndex = 0;
  226.         } else {
  227.         indexInfoPtr->blockAddrPtr++;
  228.         accessible = TRUE;
  229.         }
  230.         break;
  231.     }
  232.  
  233.     /*
  234.      * Make the block pointers accessible if necessary.
  235.      */
  236.  
  237.     if (!accessible) {
  238.     return(MakePtrAccessible(handlePtr, indexInfoPtr, descPtr));
  239.     } else {
  240.     return(SUCCESS);
  241.     }
  242. }
  243.